import sys
import time
from PyQt5.QtCore import QObject, QRunnable, QThreadPool, QTimer, pyqtSignal, pyqtSlot
from PyQt5.QtWidgets import (
    QApplication,
    QLabel,
    QMainWindow,
    QProgressBar,
    QPushButton,
    QVBoxLayout,
    QWidget,
    QMessageBox,
)


class ThreadSignals(QObject):
    progress = pyqtSignal(int)
    finished = pyqtSignal()


class Worker(QRunnable):

    def __init__(self, signal, **kwargs):
        super().__init__(**kwargs)
        self.signal = signal

    @pyqtSlot()
    def run(self) -> None:
        for i in range(100):
            self.signal.progress.emit(i + 1)
            time.sleep(0.05)
        self.signal.finished.emit()


class MainWindow(QMainWindow):

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        self.threadpool = QThreadPool()
        self.threadpool.setMaxThreadCount(6)  # my
        print(
            "Multithreading with maximum %d threads" % self.threadpool.maxThreadCount()
        )

        layout = QVBoxLayout()
        central = QWidget()
        central.setLayout(layout)

        self.progressBar = QProgressBar()
        layout.addWidget(self.progressBar)

        self.btn = QPushButton('Start')
        layout.addWidget(self.btn)
        self.btn.pressed.connect(self.btnPressed)

        self.setCentralWidget(central)

    def btnPressed(self):
        worker = Worker(ThreadSignals())
        self.threadpool.start(worker)
        worker.signal.progress.connect(self.on_progress)
        worker.signal.finished.connect(self.on_finish)

    def on_progress(self, percent):
        self.progressBar.setValue(percent)

    def on_finish(self):
        QMessageBox.information(self, "Infor", "The progress bar finished.")


app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
